class Collision
{

    //EVERYTHING BELOW THIS LINE SHOULD GO IN THE GAME CLASS
    static const float MIN_ACCURACY_SQUARED = Math.pow(0.5, 2);
    static const float STEP_SIZE = 0.02;
    //if we only check for collisions based on the range of two radii, objects can brush near each-other undetected.
    static const float MISTAKE_FACTOR = 1;

    public Vector2 collide(Object item1, Object item2)
    {
        //minDistSQ must be squared to avoid square rooting when the pythagorean theorem is used later.
        float minDistSq = Math.pow(item1.rad + item2.rad + MISTAKE_FACTOR, 2);
        //set up positions to increment through this frame's flight and keep track of each object's previous and current positions.
        Vector2 oldPos1 = null;
        Vector2 oldPos2 = null;
        Vector2 pos1 = item1.pos;
        Vector2 pos2 = item2.pos;

        while (true)
        {
            oldPos1 = pos1;
            oldPos2 = pos2;
            pos1 = new Vector2(pos1.x + STEP_SIZE * item1.vel.x, pos1.y + STEP_SIZE * item1.vel.y);
            pos2 = new Vector2(pos2.x + STEP_SIZE * item2.vel.x, pos2.y + STEP_SIZE * item2.vel.y);
            //Check the distance between the two points.
            distSq = Math.pow(pos1.x - pos2.x, 2) + Math.pow(pos1.y - pos2.y, 2);
            if (distSq < minDistSq)
            {
                break;
            }
            else if (pos1.x > (item1.pos.x + item1.vel.x))
            {
                //Print to let user know there were no collisions
                //Then exit
            }
        }

        //A collision has been found if you reached this point. Refine the collision coordinates.
        binSearch(oldPos1, oldPos2, out pos1, out pos2, minDistSq);
        return new Vector2();
    }

    private void binSearch(Vector2 oldPos1, Vector2 oldPos2, out Vector2 pos1, out Vector2 pos2, float minDistSq)
    {
        Vector2 midPos1 = new Vector2((oldPos1.x + pos1.x) / 2, (oldPos1.y + pos1.y) / 2);
        Vector2 midPos2 = new Vector2((oldPos2.x + pos2.x) / 2, (oldPos2.y + pos2.y) / 2);
        bool midPosCollides = checkCollision(midPos1, midPos2, minDistSq);

        float lastStep1Sq = Math.pow(midPos1.x - oldPos1.x, 2) + Math.pow(midPos1.y - oldPos1.y, 2);
        float lastStep2Sq = Math.pow(midPos2.x - oldPos2.x, 2) + Math.pow(midPos2.y - oldPos2.y, 2);

        if (midPosCollides)
        {
            if (lastStep1Sq < MIN_ACCURACY_SQUARED && lastStep2Sq < MIN_ACCURACY_SQUARED)
            {
                pos1 = new Vector2((midPos1.x + oldPos1.x) / 2, (midPos1.y + oldPos1.y) / 2);
                pos2 = new Vector2((midPos2.x + oldPos2.x) / 2, (midPos2.y + oldPos2.y) / 2);
                return;
            }
            else
            {
                binSearch(oldPos1, oldPos2, out midPos1, out midPos2, minDistSq);
                pos1 = midPos1;
                pos2 = midPos2;
                return;
            }
        }
        else
        {
            if (lastStep1Sq < MIN_ACCURACY_SQUARED && lastStep2Sq < MIN_ACCURACY_SQUARED)
            {
                pos1 = new Vector2((midPos1.x + pos1.x) / 2, (midPos1.y + pos1.y) / 2);
                pos2 = new Vector2((midPos2.x + pos2.x) / 2, (midPos2.y + pos2.y) / 2);
                return;
            }
            else
            {
                binSearch(midPos1, midPos2, out pos1, out pos2, minDistSq);
                return;
            }
        }
    }

    private bool checkCollision(Vector2 pos1, Vector2 pos2, float minDistSq)
    {
        distSq = Math.pow(pos1.x - pos2.x, 2) + Math.pow(pos1.y - pos2.y, 2);
        if (distSq < minDistSq)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}